"""
PyGame Mario
Seth Vanderwilt (with invaluable assistance from King Xia)
AP CS++
5/20/11

Work to do:
- add more types of enemies
- add support for more levels (level 2 not currently supported due to height problems)
- clean up code
"""

#### CURRENT PROJECT ####
# add FPS counter in corner
# make separate files for each class

###King's Notes
#Rather than more enemies, perhaps more class types,
#but those are mutable, or perhaps,
#the classes could just have latent functions

###GLITCHES, VERY IMPORTANT!###
#Make Mario unable to 'hop up' blocks
#Don't let Mario jump when he's not on the ground (just after going off a block)

# Import necessary modules
import os
import pygame
import sys
import time
from sys import exit
from pygame.locals import *
pygame.init()

# get the classes
from mario import *
from enemy import *
from hud import *
from obstacle import *

def main():
    deaths = 0
    # Load all enemies, blocks and background images
    level_name = raw_input("Select Level: ")
    user_name = raw_input("User Name: ")
##    background = pygame.image.load("mario-1-" + level_name + ".gif")

    # unfortunately, pygame.display.set_mode can't come later
    # we'll have to deal with the black window for now
    # Make a list of all the obstacles
    all_obstacles = process_obstacle_coords(level_name)
    # Must be global or the mario class can't reference it
    global BLOCKS
    BLOCKS = []
    for obstacle in all_obstacles:
        x = obstacle[0]
        y = obstacle[1]
        width = obstacle[2]
        height = obstacle[3]
        #print x,y,width,height
        BLOCKS.append(Obstacle([x,y,width, height]))
    # Make a list of all enemies
    all_enemies = process_enemy_coords(level_name)
    ENEMIES = []
##    for enemy in all_enemies:
##        ENEMIES.append(Enemy([enemy[0], enemy[1], enemy[2]]))
    # Load high-scores file
    win_file = open("win_file_" + level_name + ".txt", "a")
    # Initialize sprites and the screen caption
    pygame.mixer.init(22050, -16, 2, 4096)
    pygame.mixer.music.load('Super Mario Brothers - Overworld Remix.mp3')
    #pygame.display.set_caption('Red Luigi [alpha]')
    screen = pygame.display.set_mode((1000, 448))
    pygame.display.set_caption("Red Luigi [alpha]")
    pygame.display.set_icon(image_load("icon.png"))
    background = pygame.image.load("mario-1-" + level_name + ".gif")
    global clock
    clock = pygame.time.Clock()
    for enemy in all_enemies:
        ENEMIES.append(Enemy([enemy[0], enemy[1], enemy[2]]))
    mario = Mario()
    mario.blocks = BLOCKS
    hud = HUD(clock) # needed for FPS
    SpriteGroup = pygame.sprite.Group(mario, ENEMIES, hud)
    screen.blit(background, (mario.screenpos,0))
##    global clock
##    clock = pygame.time.Clock()
    keepGoing = True
    print("Starting Game in 3 Seconds...\n\tmake sure the PyGame window is active!")
    time.sleep(3)    # Allows time to get ready to play
    # commented this out to make launching from windows explorer work        
    # Runs the game soundtrack

    pygame.mixer.music.play(-1)
    while keepGoing:
        #print start_time
        clock.tick(30)
#        score.points -= 2
        hud.points -= 2
        # Check for clicking or quit events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
##                pygame.display.quit()
                pygame.quit()
                keepGoing = False
                
            elif event.type == MOUSEBUTTONDOWN:
                mousecoord = pygame.mouse.get_pos()
                x = mousecoord[0] - mario.screenpos
                y = mousecoord[1]
                print(str(x) + ", " + str(y))
            key = pygame.key.get_pressed()
            if key[K_a]:
                mousecoord = pygame.mouse.get_pos()
                x = mousecoord[0] - mario.screenpos
                y = mousecoord[1]
                enemyfile = open("enemy_coords_file_" + level_name + ".txt", 'r+')
                new_enemy = Enemy((x, x+200, y))
                ENEMIES.append(new_enemy)
                out = new_enemy.to_write() # not working for some reason
                enemyfile.write(out)
                print new_enemy.to_write()
        SpriteGroup.clear(screen, background)
        # Used for sidescrolling, moves blocks and enemies
        if mario.movingright and mario.rect.right > 700:
            mario.rect.right = 700
            mario.screenpos -= 10
            for block in BLOCKS:
                block.rect.centerx -= 10
            for enemy in ENEMIES:
                enemy.rect.centerx -= 10
        if mario.movingleft and mario.rect.left < 300 and mario.screenpos <= -10:
            mario.rect.left = 300
            mario.screenpos += 10
            for block in BLOCKS:
                block.rect.centerx += 10
            for enemy in ENEMIES:
                enemy.rect.centerx += 10
        # Update the enemy sprite images
        for enemy in ENEMIES:
            if enemy.rect.left < enemy.left_limit + mario.screenpos:
                enemy.dx *= -1
                enemy.image = image_load('Shyguy.gif')
            if enemy.rect.right > enemy.right_limit + mario.screenpos:
                enemy.dx *= -1
                enemy.image = image_load('Shyguyleft.gif')
        
        # Check for collision with enemies or falling off the screen
        for enemy in ENEMIES:
            if collision(mario.rect.centerx, mario.rect.centery, enemy.rect.centerx, enemy.rect.centery):
                deaths += 1
                print("Dead...\n\tYou've died " + str(deaths) + " times.")
                time.sleep(1.5)
                mario.reset()
#                score.reset()
                hud.reset()
                for block in BLOCKS:
                    block.reset()
                for enemy in ENEMIES:
                    enemy.reset()
        if mario.rect.bottom >= 448:
            deaths += 1
            print("You fell down...")
            time.sleep(1.5)
            mario.reset()
#            score.reset()
            hud.reset()
            for block in BLOCKS:
                block.reset()
            for enemy in ENEMIES:
                enemy.reset()
        # Have you beaten the level?
        if mario.screenpos <= -5650:
            print("You beat the level\n\tResetting in 3 seconds or press Esc to quit or try the next level\n\nYour score was " + str(hud.points) + ".")
            win_time = time.localtime()
            year = win_time[0]
            month = win_time[1]
            day = win_time[2]
            hour = win_time[3]
            minute = win_time[4]
            if month <= 9:
                month = "0" + str(month)
            win_file.write("User: " + user_name + " Score: " + str(hud.points) + " Time: " + str(year) + "-" + str(month) + "-" + str(day) + " " + str(hour) + ":" + str(minute) + "\n")
            time.sleep(3)
            mario.reset()
            hud.reset()
            for block in BLOCKS:
                block.reset()
            for enemy in ENEMIES:
                enemy.reset()
        # Update the display
        screen.blit(background, (mario.screenpos, 0))

        SpriteGroup.update()
        SpriteGroup.draw(screen)
        pygame.display.flip()

### commented this out to make launching from windows explorer work        
### Runs the game soundtrack
##pygame.mixer.init(22050, -16, 2, 4096)
##pygame.mixer.music.load('Super Mario Brothers - Overworld Remix.mp3')
##pygame.mixer.music.play(-1)

# Starts the game
if __name__ == "__main__":
    main()
